package com.sofa.api.config;


import com.sofa.common.context.BaseContext;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static com.sofa.api.constants.Constant.*;

@Slf4j
@Configuration
@EnableFeignClients(basePackages = "com.sofa.api.client")
public class RequestIdRelayConfiguration {

    @Bean
    public RequestInterceptor requestIdInterceptor(){
        return template -> template
                .header(REQUEST_ID_HEADER, MDC.get(REQUEST_ID_HEADER))
                .header(REQUEST_FROM_HEADER, FEIGN_ORIGIN_NAME);
    }

    //定义个拦截器,将用户信息添加到请求头中(OpenFeign传递用户信息)
    @Bean
    public RequestInterceptor userInfoRequestInterceptor() {
        return new RequestInterceptor(){
            @Override
            public void apply(RequestTemplate template) {
                //这里之所以可以用UserContext是因为网关进来的那个微服务是带了请求头的,只是转发到其他微服务中时不带
                //例如网关进到购物车的微服务,而购物车中的请求头已经携带了用户信息并且存放在了UserContext中了,所以这里可以使用
                //调用另一个微服务时已经是另一个线程了,所以LocalThread中的信息已经不同了,所以没法直接在另一个微服务中使用UserContext获取用户信息
                Long userId = BaseContext.getCurrentId();
                if(userId != null) {
                    template.header("user-info", userId.toString());
                }
                log.info("openfeign远程调用请求头中添加用户信息:{}", userId);
            }
        };
    }
}